import React, { useEffect, useState, useCallback } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { Card, Button, Typography, message, Progress, Space, Form, Input, Modal, Upload } from 'antd';
import { PlusOutlined, UploadOutlined, UserOutlined } from '@ant-design/icons';
import axios from 'axios';
import { ethers } from 'ethers';
import { votingFactoryAbi, votingFactoryAddress } from '../chain/votingFactory';
import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip } from 'recharts';
import type { UploadFile } from 'antd/es/upload/interface';
import type { RcFile } from 'antd/es/upload';

const { Title, Text } = Typography;

interface Candidate {
  _id: string;
  name: string;
  signature?: string;
  imageUrl?: string;
  votes?: number;
  isCustom?: boolean;
  addedBy?: string;
  addedAt?: Date;
}

const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042', '#8884D8', '#82CA9D'];

interface ChartData {
  name: string;
  value: number;
  color: string;
}

const VotePage: React.FC = () => {
  const { voteId } = useParams();
  const [vote, setVote] = useState<any>(null);
  const [selected, setSelected] = useState<number | null>(null);
  const [voteLoadingIdx, setVoteLoadingIdx] = useState<number | null>(null);
  const [cancelLoadingIdx, setCancelLoadingIdx] = useState<number | null>(null);
  const [abstainLoading, setAbstainLoading] = useState(false);
  const [userAddress, setUserAddress] = useState<string | null>(null);
  const [expired, setExpired] = useState(false);
  const navigate = useNavigate();
  const [isAddCandidateModalVisible, setIsAddCandidateModalVisible] = useState(false);
  const [addCandidateForm] = Form.useForm();
  const [addCandidateFileList, setAddCandidateFileList] = useState<UploadFile[]>([]);
  const [addCandidateLoading, setAddCandidateLoading] = useState(false);

  useEffect(() => {
    if ((window as any).ethereum && (window as any).ethereum.selectedAddress) {
      setUserAddress((window as any).ethereum.selectedAddress);
    }
  }, []);

  // 获取投票信息的逻辑
  const fetchVote = useCallback(async () => {
    try {
      const res = await axios.get(`/api/vote/${voteId}`);
      const voteData = res.data.data;
      let candidatesWithVotes = [];
      let currentVoters = 0;
      let maxVoters = 0;
      let isExpired = false;

      if ((window as any).ethereum && voteData.chainVoteId !== undefined && voteData.chainVoteId !== null) {
        const provider = new ethers.BrowserProvider((window as any).ethereum);
        const contract = new ethers.Contract(votingFactoryAddress, votingFactoryAbi, provider);

        const voteInfo = await contract.getVote(voteData.chainVoteId);
        const candidateCount = Number(voteInfo[3]);
        maxVoters = Number(voteInfo[4]);
        currentVoters = Number(voteInfo[5]);
        if (voteData.expireAt) {
          const expireAt = typeof voteData.expireAt === 'string' ? new Date(voteData.expireAt) : voteData.expireAt;
          if (expireAt < new Date()) isExpired = true;
        }
        if (voteData.expired === true) isExpired = true;
        if (currentVoters >= maxVoters) isExpired = true;

        const chainCandidates = [];
        for (let i = 0; i < candidateCount; i++) {
          try {
            const [name, signature, imageUrl, addedBy, addedAt] = await contract.getCandidate(voteData.chainVoteId, i);
            const votes = await contract.getCandidateVotes(voteData.chainVoteId, i);
            const mongoCandidate = voteData.candidates.find((c: any) => c.name === name);
            chainCandidates.push({
              _id: mongoCandidate?._id || i,
              name,
              signature,
              imageUrl: mongoCandidate?.imageUrl || imageUrl,
              votes: Number(votes),
              isCustom: !!addedBy,
              addedBy,
              addedAt: new Date(Number(addedAt) * 1000)
            });
          } catch (e) {}
        }
        candidatesWithVotes = chainCandidates;
      } else {
        candidatesWithVotes = voteData.candidates.map((c: any) => ({ ...c, votes: 0 }));
        maxVoters = voteData.maxVoters || 0;
        currentVoters = voteData.currentVoters || 0;
        if (voteData.expireAt) {
          const expireAt = typeof voteData.expireAt === 'string' ? new Date(voteData.expireAt) : voteData.expireAt;
          if (expireAt < new Date()) isExpired = true;
        }
        if (voteData.expired === true) isExpired = true;
        if (currentVoters >= maxVoters) isExpired = true;
      }

      setExpired(isExpired);
      setVote({
        ...voteData,
        candidates: candidatesWithVotes,
        maxVoters,
        currentVoters
      });
    } catch (err: any) {
      console.error('获取投票信息失败:', err);
      message.error('获取投票信息失败');
    }
  }, [voteId, userAddress]);

  // 添加调试信息
  useEffect(() => {
    console.log('VotePage - 当前状态:', {
      userAddress,
      selected,
      expired,
      vote: vote ? {
        chainVoteId: vote.chainVoteId,
        candidates: vote.candidates.length,
        maxVoters: vote.maxVoters,
        currentVoters: vote.currentVoters,
        voteName: vote.voteName
      } : null,
      buttonDisabled: {
        reason: {
          noWallet: !userAddress,
          alreadyVoted: selected !== null,
          expired: expired,
          details: {
            userAddress: userAddress ? '已连接' : '未连接',
            selected: selected === null ? '未投票' : selected === -1 ? '已弃权' : `已投票给候选人${selected + 1}`,
            expired: expired ? '已过期' : '未过期'
          }
        }
      }
    });
  }, [userAddress, selected, expired, vote]);

  // 在组件加载时调用 fetchVote
  useEffect(() => {
    fetchVote();
  }, [fetchVote]);

  // 连接MetaMask钱包
  const connectWallet = async () => {
    if (!(window as any).ethereum) {
      message.error('请先安装MetaMask钱包');
      return false;
    }
    try {
      const accounts = await (window as any).ethereum.request({ method: 'eth_requestAccounts' });
      setUserAddress(accounts[0]);
      return true;
    } catch (error) {
      message.error('连接钱包失败');
      return false;
    }
  };

  // 投票
  const handleVote = async (candidateIdx: number) => {
    let address = userAddress;
    if (!address) {
      const connected = await connectWallet();
      if (!connected) return;
      address = (window as any).ethereum.selectedAddress.toLowerCase();
      console.log('连接钱包成功，地址:', address);
      setUserAddress(address);
    }
    
    if (selected !== null) {
      message.warning('每人只允许投一票，如需重新投票请先取消投票');
      return;
    }
    
    if (typeof vote?.chainVoteId !== 'number' || isNaN(vote.chainVoteId) || vote.chainVoteId < 0) {
      message.error('投票ID无效');
      return;
    }
    
    if (typeof candidateIdx !== 'number' || candidateIdx < 0 || candidateIdx >= vote.candidates.length) {
      message.error('候选人参数错误');
      return;
    }

    
    
    console.log('投票参数:', {
      chainVoteId: vote.chainVoteId,
      candidateIdx,
      address,
      voteName: vote.voteName
    });
    
    //执行投票
    setVoteLoadingIdx(candidateIdx);
    try {
      const provider = new ethers.BrowserProvider((window as any).ethereum);
      const signer = await provider.getSigner();
      const contract = new ethers.Contract(votingFactoryAddress, votingFactoryAbi, signer);
      
      console.log('开始调用合约投票...');
      const tx = await contract.castVote(vote.chainVoteId, candidateIdx);
      console.log('投票交易已发送:', tx.hash);
      
      await tx.wait();
      console.log('投票交易已确认');
      
      // 记录参与者地址
      await axios.post('/api/vote/record-voter', {
        voteId: vote._id,
        address: userAddress
      });
      
      setSelected(candidateIdx);
      message.success('投票成功');
      
      // 刷新投票信息
      await fetchVote();
    } catch (err) {
      console.error('投票失败:', err);
      message.error('投票失败');
    } finally {
      setVoteLoadingIdx(null);
    }
  };

  // 取消投票
  const handleCancelVote = async () => {
    if (!userAddress) {
      message.warning('请先连接钱包');
      return;
    }
    
    if (selected === null || !vote?.chainVoteId) {
      return;
    }
    
    setCancelLoadingIdx(selected);
    try {
      const provider = new ethers.BrowserProvider((window as any).ethereum);
      const signer = await provider.getSigner();
      const contract = new ethers.Contract(votingFactoryAddress, votingFactoryAbi, signer);
      
      // 使用chainVoteId取消投票
      const tx = await contract.cancelVote(vote.chainVoteId);
      await tx.wait();
      
      setSelected(null);
      message.success('已取消投票');
      
      // 刷新投票信息
      await fetchVote();
    } catch (err) {
      console.error('取消投票失败:', err);
      message.error('取消投票失败');
    } finally {
      setCancelLoadingIdx(null);
    }
  };

  // 弃权
  const handleAbstain = async () => {
    let address = userAddress;
    if (!address) {
      const connected = await connectWallet();
      if (!connected) return;
      address = (window as any).ethereum.selectedAddress.toLowerCase();
      setUserAddress(address);
    }
    
    if (selected !== null) {
      message.warning('您已经投票或弃权，不能重复操作');
      return;
    }
    
    if (!vote?.chainVoteId) {
      message.error('投票ID无效');
      return;
    }
    
    setAbstainLoading(true);
    try {
      const provider = new ethers.BrowserProvider((window as any).ethereum);
      const signer = await provider.getSigner();
      const contract = new ethers.Contract(votingFactoryAddress, votingFactoryAbi, signer);
      
      const tx = await contract.abstain(vote.chainVoteId);
      await tx.wait();
      
      // 记录参与者地址
      await axios.post('/api/vote/record-voter', {
        voteId: vote._id,
        address: userAddress
      });
      
      setSelected(-1);
      message.success('弃权成功');
      
      await fetchVote();
    } catch (err) {
      console.error('弃权失败:', err);
      message.error('弃权失败');
    } finally {
      setAbstainLoading(false);
    }
  };

  // 处理添加候选
  const handleAddCandidate = () => {
    if (!userAddress) {
      message.warning('请先连接钱包');
      return;
    }
    if (selected !== null) {
      message.warning('您已经投票，不能添加候选');
      return;
    }
    if (expired) {
      message.warning('投票已结束，不能添加候选');
      return;
    }
    setIsAddCandidateModalVisible(true);
    addCandidateForm.resetFields();
    setAddCandidateFileList([]);
  };

  // 处理添加候选确认
  const handleAddCandidateOk = async (values: any) => {
    if (!userAddress) {
      message.warning('请先连接钱包');
      return;
    }

    // 前端查重
    const exists = vote?.candidates.some(
      (c: Candidate) => c.name.trim().toLowerCase() === values.candidateName.trim().toLowerCase()
    );
    if (exists) {
      message.error('该候选名称已存在，请使用其他名称');
      return;
    }

    setAddCandidateLoading(true);
    try {
      // 1. 先链上添加候选
      const provider = new ethers.BrowserProvider((window as any).ethereum);
      const signer = await provider.getSigner();
      const contract = new ethers.Contract(votingFactoryAddress, votingFactoryAbi, signer);

      // 检查投票是否存在
      const voteInfo = await contract.getVote(vote.chainVoteId);
      if (!voteInfo) {
        throw new Error('投票不存在');
      }

      // 添加候选到链上
      const tx = await contract.addCandidate(
        vote.chainVoteId,
        values.candidateName,
        values.candidateSignature || "",
        values.imageUrl || ""
      );
      message.info('等待链上交易确认...');
      const receipt = await tx.wait();

      // 2. 再链下同步
      const res = await axios.post(`/api/vote/${voteId}/add-candidate`, {
        name: values.candidateName,
        signature: values.candidateSignature || "",
        imageUrl: values.imageUrl || "",
        address: userAddress.toLowerCase()
      });

      if (!res.data.success) {
        throw new Error(res.data.message || '添加候选失败');
      }

      message.success('添加候选成功');
      setIsAddCandidateModalVisible(false);
      addCandidateForm.resetFields();
      setAddCandidateFileList([]);

      // 3. 刷新投票信息
      await fetchVote();

    } catch (err: any) {
      console.error('添加候选失败:', err);
      message.error(err.message || '添加候选失败，请重试');
    } finally {
      setAddCandidateLoading(false);
    }
  };

  // 处理添加候选取消
  const handleAddCandidateCancel = () => {
    setIsAddCandidateModalVisible(false);
    addCandidateForm.resetFields();
    setAddCandidateFileList([]);
  };

  // 处理文件上传前的验证
  const beforeUpload = (file: RcFile) => {
    const isImage = file.type.startsWith('image/');
    if (!isImage) {
      message.error('只能上传图片文件！');
    }
    const isLt2M = file.size / 1024 / 1024 < 2;
    if (!isLt2M) {
      message.error('图片大小不能超过 2MB！');
    }
    return isImage && isLt2M ? false : Upload.LIST_IGNORE;
  };

  // 处理文件上传变化
  const handleUploadChange = ({ fileList: newFileList }: { fileList: UploadFile[] }) => {
    setAddCandidateFileList(newFileList.filter(file => file.status !== 'removed'));
  };

  const renderVoteChart = () => {
    if (!vote?.candidates) return null;
    
    const totalVotes = vote.candidates.reduce((sum: number, c: Candidate) => sum + (c.votes || 0), 0);

    // 构造数据
    const data: ChartData[] = vote.candidates.map((c: Candidate, index: number) => ({
      name: c.name,
      value: c.votes || 0,
      color: totalVotes === 0 ? '#e0e0e0' : COLORS[index % COLORS.length] // 没有投票时用灰色
    }));

    return (
      <div style={{ height: 300, marginBottom: 24, position: 'relative' }}>
        <ResponsiveContainer width="100%" height="100%">
          <PieChart>
            <Pie
              data={data}
              cx="50%"
              cy="50%"
              labelLine={false}
              label={({ name, percent }: { name: string; percent: number }) =>
                totalVotes === 0 ? '' : `${name}: ${(percent * 100).toFixed(0)}%`
              }
              outerRadius={80}
              fill="#8884d8"
              dataKey="value"
            >
              {data.map((entry: ChartData, index: number) => (
                <Cell key={`cell-${index}`} fill={entry.color} />
              ))}
            </Pie>
            <Tooltip />
          </PieChart>
        </ResponsiveContainer>
        {totalVotes === 0 && (
          <div
            style={{
              position: 'absolute',
              top: '50%',
              left: '50%',
              transform: 'translate(-50%, -50%)',
              color: '#aaa',
              fontSize: 20,
              pointerEvents: 'none'
            }}
          >
            暂无投票数据
          </div>
        )}
      </div>
    );
  };

  return (
    <div style={{ maxWidth: 800, margin: '0 auto', marginTop: 32 }}>
      {!vote ? (
        <Title level={4}>加载中...</Title>
      ) : (
        <>
          <Title level={3}>{vote.voteName}</Title>
          {expired && (
            <div style={{ marginBottom: 16, color: 'red', fontWeight: 'bold' }}>
              投票已结束，您不能再进行任何操作
            </div>
          )}
          {vote.maxVoters && (
            <div style={{ marginBottom: 16 }}>
              <Text>投票进度：</Text>
              <Progress 
                percent={Math.round((vote.currentVoters / vote.maxVoters) * 100)} 
                status={expired ? "exception" : "active"}
                format={percent => `${vote.currentVoters}/${vote.maxVoters}`}
              />
            </div>
          )}
          
          {renderVoteChart()}

          <div>
            {vote.candidates.map((c: Candidate, idx: number) => (
              <Card key={c._id} style={{ marginBottom: 16 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
                  {c.imageUrl ? (
                    <img src={c.imageUrl} alt={c.name} style={{ width: 50, height: 50, borderRadius: 8 }} />
                  ) : (
                    <UserOutlined style={{ fontSize: 30 }} />
                  )}
                  <div style={{ flex: 1 }}>
                    <Text strong>{c.name}</Text>
                    {c.signature && <div><Text type="secondary">{c.signature}</Text></div>}
      
                  </div>
                  <div>
                    <Button
                      type="primary"
                      disabled={
                        expired || 
                        selected !== null || 
                        !userAddress || 
                        (c.isCustom && c.addedBy === userAddress?.toLowerCase())
                        
                      }
                      onClick={() => handleVote(idx)}
                      loading={voteLoadingIdx === idx}
                      style={{ marginRight: 8 }}
                    >
                      投票
                    </Button>
                    <Button
                      danger
                      disabled={expired || selected !== idx || !userAddress}
                      onClick={handleCancelVote}
                      loading={cancelLoadingIdx === idx}
                    >
                      取消投票
                    </Button>
                  </div>
                  <div style={{ marginLeft: 16 }}>
                    <Text>票数：{c.votes ?? 0}</Text>
                  </div>
                </div>
              </Card>
            ))}
          </div>

          <Space style={{ marginTop: 32 }}>
            <Button
              type="primary"
              onClick={() => navigate('/main')}
            >
              返回
            </Button>
            <Button
              type="default"
              icon={<PlusOutlined />}
              onClick={handleAddCandidate}
              disabled={expired || selected !== null || !userAddress}
            >
              添加候选
            </Button>
            <Button
              type="default"
              disabled={expired || selected !== null || !userAddress}
              onClick={handleAbstain}
              loading={abstainLoading}
            >
              弃权
            </Button>
          </Space>

          {/* 添加候选的模态框 */}
          <Modal
            title="添加候选"
            open={isAddCandidateModalVisible}
            onOk={() => addCandidateForm.submit()}
            onCancel={handleAddCandidateCancel}
            confirmLoading={addCandidateLoading}
            okText="确定"
            cancelText="取消"
          >
            <Form
              form={addCandidateForm}
              layout="vertical"
              onFinish={handleAddCandidateOk}
            >
              <Form.Item
                name="candidateName"
                label="名称"
                rules={[{ required: true, message: '请输入名称' }]}
              >
                <Input placeholder="请输入名称" />
              </Form.Item>
              <Form.Item
                name="candidateSignature"
                label="介绍（可选）"
              >
                <Input.TextArea placeholder="请输入介绍（可选）" />
              </Form.Item>
              <Form.Item label="上传图片（可选）">
                <Upload
                  listType="picture"
                  maxCount={1}
                  beforeUpload={beforeUpload}
                  onChange={handleUploadChange}
                  fileList={addCandidateFileList}
                >
                  <Button icon={<UploadOutlined />}>上传图片</Button>
                </Upload>
              </Form.Item>
            </Form>
          </Modal>
        </>
      )}
    </div>
  );
};

export default VotePage;
